#ifndef PoolAllocator_h__
#define PoolAllocator_h__

namespace inf {
    template<class T>
    class Allocator {
    public:
        Allocator( int granularity=4096 );
        ~Allocator();

        T *alloc( void );
    private:
        // ==============================================================================
        //! Create/Append a new chunk
        // ==============================================================================
        void create_chunk( void );

        // ==============================================================================
        //! Holds an array of T with the size of granularity
        // ==============================================================================
        struct allocChunk_t {
            T *	list;
            int	last;
        };
        inf::List<allocChunk_t>     allocationList;	//!< List of all chunks
        int granularity;					//!< The granularity
    };

    template<class T>
    Allocator<T>::Allocator( int _granularity ) : granularity(_granularity) {
        create_chunk();
    }

    template<class T>
    Allocator<T>::~Allocator() {
        int num = allocationList.size();
        for( int i=0; i<num; i++ )
            delete[] allocationList[i].list;
        allocationList.clear();
    }

    template<class T>
    void Allocator<T>::create_chunk( void ) {
        allocChunk_t &chunk = allocationList.alloc_to_back();
        chunk.last = 0;
        chunk.list = new T[granularity];
    }

    template<class T>
    T *Allocator<T>::alloc( void ) {
        allocChunk_t &chunk = allocationList[allocationList.size()-1];
        T *ret = &chunk.list[chunk.last];
        chunk.last++;
        if ( chunk.last >= granularity )
            create_chunk();
        return ret;
    }


}   // ::inf

#endif // PoolAllocator_h__
